package remoting
{
	
	import flash.display.Sprite;
	import flash.events.*;
	import flash.net.NetConnection;
	import flash.net.ObjectEncoding;
	import flash.net.Responder;
	import flash.utils.Timer;
	
	import vo.UserVO;
	import log.Logger;
	import manager.GameMgr;
	
	/**
	 * -- Server --
	 * @desc	a class used to communicate with php side
	 * @author	Aqua (built on 2011-11-10)
	 */
	public class Server
	{
		//---------------------//
		//     Constructor     //
		//---------------------//
		
		/**************************************************************************
		 * -- Server --
		 * @desc		constructor
		 *************************************************************************/
		public function Server():void
		{
			
		}
		
		
		//-----------------//
		//     Publics     //
		//-----------------//
		
		/**************************************************************************
		 * -- (setter) error --
		 * @desc		set error type
		 * @param		(err) error type
		 *************************************************************************/
		public static function set error(err:String):void
		{
			_error = err;
		}
		
		/**************************************************************************
		 * -- connet --
		 * @desc		start to connect to server
		 * @param		(resp) response function which needs to be called when connected
		 *************************************************************************/
		public static function connet(response:Function) :void
		{
			Logger.log("** start connecting to server");
			
			if (_nc)
			{
				_nc.close();
			}
			
			_error = "";
			_nc = new NetConnection();
			_nc.objectEncoding = ObjectEncoding.AMF3;
			_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_nc.connect(GameMgr.instance.localMode ? AMF_GATEWAY_LOCAL : AMF_GATEWAY);
			//_nc.connect(AMF_GATEWAY);
			
			// check if client version is the same as server version
			call(Method.CHECK_VERSION, onResult, {"version":CLIENT_VERSION});
			
			function onResult(res:Object):void
			{
				if (res.rightVersion)
				{
					Logger.log("** version checked");
					response();
				}
				else
				{
					error = ERROR_OLD_CLIENT_VERSION;
					popupError();
				}
			}
		}
		
		/**************************************************************************
		 * -- call --
		 * @desc		call php method
		 * @param		(method) name of method
		 * @param		(response) response function called when method succeeds
		 * @param		(param)	param of method
		 *************************************************************************/
		public static function call(method:String, response:Function, param:Object):void
		{
			var command:Command;
			
			command = new Command(method, response, param, callServerMethod);
			command.excute();
		}
		
		/**************************************************************************
		 * -- popupError --
		 * @desc		popup error window, tell user error has occured
		 *************************************************************************/
		public static function popupError():void
		{
			Logger.log("Error: " + _error);
		}
		
		
		//------------------//
		//     Privates     //
		//------------------//
		
		/**************************************************************************
		 * -- netStatusHandler --
		 * @desc		handler of connetion status event
		 * @param		(e) event information
		 *************************************************************************/
		private static function netStatusHandler(e:NetStatusEvent):void
		{
			switch(e.info.code)
			{
				case "NetConnection.Call.BadVersion":
					error = ERROR_AMF_BAD_VERSION;
					popupError();
					break;
				default:
					break;
			}
		}
		
		/**************************************************************************
		 * -- callServerMethod --
		 * @desc		call php method to operation database
		 * @param		(method) name of method
		 * @param		(rsp) a responder which includes handlers on success and fail
		 * @param		(param)	param of method, can be null
		 *************************************************************************/
		private static function callServerMethod(method:String, rsp:Responder, param:Object):void
		{
			Logger.log("call server method: " + method);
			
			var obj:Object;
			
			obj = { "server_id":SERVER_ID, "data":param };
			_nc.call(method, rsp, obj);
		}
		
		
		public static const OPERATION_SUCCEED			:int	= 1;
		public static const OPERATION_FAIL				:int	= 0;
		
		public static const ERROR_OLD_CLIENT_VERSION	:String	= "ERROR_OLD_CLIENT_VERSION";
		public static const ERROR_TIME_OUT				:String	= "ERROR_TIME_OUT";
		public static const ERROR_RESPONSE_FAIL			:String	= "ERROR_RESPONSE_FAIL";
		public static const ERROR_AMF_BAD_VERSION		:String	= "ERROR_AMF_BAD_VERSION";
		public static const ERROR_OPERATION_FAIL		:String	= "ERROR_OPERATION_FAIL";
		
		private static const SERVER_ID			:String	= "Saber!!!";
		private static const CLIENT_VERSION		:String = "0.50.01";
		private static const AMF_GATEWAY_LOCAL	:String	= "http://localhost/bbs/ZendAMF/amf.php";
		//private static const AMF_GATEWAY_LOCAL	:String = "http://tigana.us18.beidc.net/dstepdeploy/ZendAMF/amf.php";
		private static const AMF_GATEWAY		:String = "http://tigana.us18.beidc.net/dstepdeploy/ZendAMF/amf.php";

		private static var _nc		:NetConnection;
		private static var _error	:String;
	}
	
}